use model::version_manifest::MVersion;

use crate::{get, Downloadable};

impl Downloadable for MVersion {
  fn download(
    &self,
    game_dir: &std::path::Path,
  ) -> Result<(), Box<dyn std::error::Error>> {
    let game_url = get(&self.url)?.json::<model::version::Version>()?;

    let version_as_dir = &game_dir.join("versions").join(&game_url.id);

    if !version_as_dir.exists() {
      std::fs::create_dir_all(version_as_dir)?;
    }
    // download deps lib and resource asset
    game_url.libraries.download(game_dir)?;
    game_url.asset_index.download(game_dir)?;

    let version_config = &game_dir
      .join("versions")
      .join(&game_url.id)
      .join(&format!("{}.json", &self.id));

    if version_config.exists() {
      std::fs::remove_file(version_config)?;
    }

    std::fs::File::create(version_config)?;
    std::fs::write(version_config, get(&self.url)?.bytes()?)?;

    let to_write_path = &game_dir
      .join("versions")
      .join(&game_url.id)
      .join(&format!("{}.jar", &game_url.id));

    if to_write_path.exists() {
      if crate::sha1(to_write_path)?.eq(&game_url.downloads.client.sha1) {
        return Ok(());
      } else {
        std::fs::remove_file(to_write_path)?;
      }
    }

    std::fs::File::create(to_write_path)?;

    let bytes = get(&game_url.downloads.client.url)?.bytes()?;

    std::fs::write(to_write_path, bytes)?;

    Ok(())
  }
}
